package com.zhss.dfs.server;

import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @Author liu Weidong
 * @Email:
 * @Date: 2024/5/28 14:18
 * @Version 1.0
 */
public class ReplicaFileTask extends Thread {


    private ConcurrentLinkedQueue<String> copyTaskQueue;

    private NIOClient nioClient;

    public ReplicaFileTask() {
        this.copyTaskQueue = new ConcurrentLinkedQueue<>();
        this.nioClient = new NIOClient();
    }

    @Override
    public void run() {
        FileOutputStream outputStream = null;
        FileChannel channel = null;
        while (true) {
            try {
                if (copyTaskQueue.isEmpty()) {
                    TimeUnit.MILLISECONDS.sleep(10000);
                }
                String task = copyTaskQueue.poll();
                JSONObject jsonObject = JSONObject.parseObject(task);
                Long fileLength = jsonObject.getLong("fileLength");
                String fileName = jsonObject.getString("fileName");
                JSONObject sourceDataNode = jsonObject.getJSONObject("sourceDataNode");
                String hostname = sourceDataNode.getString("hostname");
                Integer port = sourceDataNode.getInteger("port");
                // 进行拷贝
                byte[] bytes = this.nioClient.readFile(fileName, hostname, port);
                String absoluteFileName = getAbsoluteFileName(fileName);
                // 写入本地文件
                outputStream = new FileOutputStream(absoluteFileName);
                channel = outputStream.getChannel();
                channel.write(ByteBuffer.wrap(bytes));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (channel != null) {
                    try {
                        channel.close();
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            }
        }
    }

    private String getAbsoluteFileName(String filePath) {
        String parentDir = DataNodeConfig.FILE_DATA +
                filePath.substring(0, filePath.lastIndexOf("/"));
        File file = new File(parentDir);
        if (!file.exists()) {
            file.mkdirs();
        }
        return DataNodeConfig.FILE_DATA + filePath;
    }
}
